package com.benjaminwan.read.free.ui.script

import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.View
import android.view.ViewGroup
import com.airbnb.mvrx.MvRx
import com.airbnb.mvrx.activityViewModel
import com.airbnb.mvrx.args
import com.airbnb.mvrx.withState
import com.benjaminwan.read.free.R
import com.benjaminwan.read.free.base.adapter.simpleController
import com.benjaminwan.read.free.base.fragment.BaseFragment
import com.benjaminwan.read.free.base.viewmodel.state
import com.benjaminwan.read.free.config.DelayConfig.getDelayConfig
import com.benjaminwan.read.free.config.KeyboardClickConfig.getKeyboardClickConfig
import com.benjaminwan.read.free.config.KeyboardKeyDownConfig.getKeyboardKeyDownConfig
import com.benjaminwan.read.free.config.KeyboardKeyUpConfig.getKeyboardKeyUpConfig
import com.benjaminwan.read.free.config.MouseButtonClickConfig.getMouseButtonClickConfig
import com.benjaminwan.read.free.config.MouseButtonDownConfig.getMouseButtonDownConfig
import com.benjaminwan.read.free.config.MouseButtonUpConfig.getMouseButtonUpConfig
import com.benjaminwan.read.free.config.MouseDragPageConfig.getMouseDragPageConfig
import com.benjaminwan.read.free.config.MouseMoveConfig.getMouseMoveConfig
import com.benjaminwan.read.free.config.MouseMoveLongConfig.getMouseMoveLongConfig
import com.benjaminwan.read.free.config.MouseScrollConfig.getMouseScrollConfig
import com.benjaminwan.read.free.config.ScriptConfig.getScriptConfig
import com.benjaminwan.read.free.databinding.FragmentActionBinding
import com.benjaminwan.read.free.model.action.Action
import com.benjaminwan.read.free.model.action.Delay
import com.benjaminwan.read.free.model.action.KeyboardClick
import com.benjaminwan.read.free.model.action.KeyboardKeyDown
import com.benjaminwan.read.free.model.action.KeyboardKeyUp
import com.benjaminwan.read.free.model.action.MouseButtonClick
import com.benjaminwan.read.free.model.action.MouseButtonDown
import com.benjaminwan.read.free.model.action.MouseButtonUp
import com.benjaminwan.read.free.model.action.MouseDragPage
import com.benjaminwan.read.free.model.action.MouseMove
import com.benjaminwan.read.free.model.action.MouseMoveLong
import com.benjaminwan.read.free.model.action.MouseScroll
import com.benjaminwan.read.free.model.action.Position
import com.benjaminwan.read.free.ui.main.MainState
import com.benjaminwan.read.free.ui.main.MainViewModel
import com.benjaminwan.read.free.utils.setMarginItemDecoration
import com.benjaminwan.read.free.utils.setTitle
import com.benjaminwan.read.free.views.superTextViewItemView

class ActionFragment : BaseFragment(), View.OnClickListener {
    companion object {
        fun arg(pos: Position): Bundle {
            val args = Bundle()
            args.putParcelable(MvRx.KEY_ARG, pos)
            return args
        }
    }

    private val pos by args<Position>()

    private val mainVM by activityViewModel(MainViewModel::class)
    private val epoxyController by lazy { epoxyController() }

    private val action: Action?
        get() = if (pos.idGroup < 0 || pos.idAction < 0) {
            null
        } else {
            mainVM.state.script.groups[pos.idGroup].actions[pos.idAction]
        }


    private fun action(main: MainState): Action? =
        if (pos.idGroup < 0 || pos.idAction < 0) {
            null
        } else {
            main.script.groups[pos.idGroup].actions[pos.idAction]
        }

    private lateinit var binding: FragmentActionBinding

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = FragmentActionBinding.inflate(layoutInflater)
        return binding.root
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        epoxyController.onRestoreInstanceState(savedInstanceState)
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        epoxyController.onSaveInstanceState(outState)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        setHasOptionsMenu(true)
        initViews()
    }

    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        menu.clear()
    }

    private fun initViews() {
        val action = action
        val title =
            if (action == null) "Global Config" else "Group${pos.idGroup + 1}-Action${pos.idAction + 1}-${action.actionType}"
        setTitle(title)
        binding.actionSettingRv.setHasFixedSize(true)
        binding.actionSettingRv.setMarginItemDecoration(2, 1, 2, 1)
        binding.actionSettingRv.setController(epoxyController)
        val guideStr = when (action) {
            null -> getString(R.string.guide_script)
            is Delay -> getString(R.string.guide_delay)
            is KeyboardClick -> getString(R.string.guide_keyboard_click)
            is MouseDragPage -> getString(R.string.guide_mouse_drag_page)
            is KeyboardKeyDown -> getString(R.string.guide_keyboard_key_down)
            is KeyboardKeyUp -> getString(R.string.guide_keyboard_key_up)
            is MouseButtonClick -> getString(R.string.guide_mouse_button_click)
            is MouseButtonDown -> getString(R.string.guide_mouse_button_down)
            is MouseButtonUp -> getString(R.string.guide_mouse_button_up)
            is MouseMove -> getString(R.string.guide_mouse_move)
            is MouseMoveLong -> getString(R.string.guide_mouse_move_long)
            is MouseScroll -> getString(R.string.guide_mouse_scroll)
            else -> ""
        }
        if (guideStr.isNotEmpty()) {
            binding.guideTv.text = guideStr
        } else {
            binding.guideTv.visibility = View.GONE
        }
    }

    override fun onClick(view: View?) {
        view ?: return
        when (view.id) {
            else -> {
            }
        }
    }

    override fun invalidate() = withState(mainVM) { main ->
        requireActivity().invalidateOptionsMenu()
        binding.actionSettingRv.requestModelBuild()
    }

    private fun epoxyController() = simpleController(mainVM) { main ->
        val action = action(main)
        val configList = when (action) {
            null -> getScriptConfig(mainVM)
            is Delay -> getDelayConfig(mainVM, pos)
            is KeyboardClick -> getKeyboardClickConfig(mainVM, pos)
            is KeyboardKeyDown -> getKeyboardKeyDownConfig(mainVM, pos)
            is KeyboardKeyUp -> getKeyboardKeyUpConfig(mainVM, pos)
            is MouseButtonClick -> getMouseButtonClickConfig(mainVM, pos)
            is MouseButtonDown -> getMouseButtonDownConfig(mainVM, pos)
            is MouseButtonUp -> getMouseButtonUpConfig(mainVM, pos)
            is MouseDragPage -> getMouseDragPageConfig(mainVM, pos)
            is MouseScroll -> getMouseScrollConfig(mainVM, pos)
            is MouseMove -> getMouseMoveConfig(mainVM, pos)
            is MouseMoveLong -> getMouseMoveLongConfig(mainVM, pos)
            else -> {
                emptyList()
            }
        }
        for ((index, item) in configList.withIndex()) {
            superTextViewItemView {
                id("ActionSettings:$index${item.hashCode()}")
                enable(true)
                itemType(item.type)
                leftText(item.leftText)
                rightText(item.rightText)
                isChecked(item.isChecked)
                visibility(item.visibility)
                onClickListener { view ->
                    item.click(view)
                }
                onCheckedChangeListener { buttonView, isChecked ->
                    item.checkedChange(buttonView, isChecked)
                }
            }
        }
    }

}